Custom Classes

Creating your own custom classes to extend the NLB Framework is intended to be relatively straightforward and is actively encouraged. This can be done by creating a new class that extends an existing one, and then overriding some of the lifecycle methods in order to customise its behaviour.

However, to be effective as a Building Information Model (BIM), the application user interface and other classes need to be able to search for and find out all sorts of information about your class. This means that you need to ensure that your class includes whatever boilerplate code is required to provide that information on demand. If you are simply extending an existing type component class such as BIM.Chairs to create your own custom chair type, then there will only be a little bit of boilerplate required to provide the user interface with its name and description as the core component class will already handle everything else. However, if you are creating a class for a custom type that isn't already defined by core classes, then your class will need to provide more boilerplate to describe the new type as well.

All BIM entities and elements need to provide a fully namespaced class name, a class description, an entity type and a display name. A BIM component also needs to provide a host element class so that it can be instantiated by dragging/dropping or edited within the component designer, as well as a means of determining if it is compatible with a selected element so that it can be dynamically added to menus and available component lists only when appropriate. As the framework needs to work with available classes rather than object instances, all of this information is provided by static methods on each class.

The example below shows the basic boilerplate for a type component class that creates a custom lounge chair.

MyChairs.SpecialChair = class extends BIM.Chairs.Couch {

    constructor(config, typeName) {

        super(config, typeName || 'SpecialChair');

        // TODO: Add custom parameters here...

    };

    // --------------------------------------------------------------------
    // Instance Methods.

    get isSpecialChair() {
        return true;
    };

    // --------------------------------------------------------------------
    // Overridden Instance Methods.

    rebuild(chair) {
        // TODO: Use parameters to add geometry to chair element's shell.
    };

    // --------------------------------------------------------------------
    // Overridden Static Methods - Entity.

    static getDisplayName() {
        return 'My Special Chair';
    };

    static getClassDescription() {
        return 'A parametric reclining chair with motorised foot and back rest.';
    };

    static getClassName() {
        return 'MyChairs.SpecialChair';
    };

};

// Register type component with an SVG icon.
PD.Registry.registerClass(MyChairs.SpecialChair, {
    content: '<g fill="none" stroke="currentColor"><path d="M10 10L990 0L990 990L0 990z" stroke-width="20"/></g>'
});

Custom Entity Types

In addition to the core entity types available in BIM.ENTITY, you can also create custom entity types and register new classes with that type.

The example below shows a custom component class that uses a its own custom entity type.

// Create and register a new entity type.
const g_myNewEntityTypeValue = BIM.ENTITY.addCustomType('NewEntity');

// Create new entity class.
MyLibrary.MyNewComponent = class extends BIM.Component {

    constructor(config, typeName) {
        super(config, typeName || 'MyNewComponent');
    };

    // --------------------------------------------------------------------
    // Instance Methods.

    get isMyNewComponent() {
        return true;
    };

    // --------------------------------------------------------------------
    // Overridden Instance Methods.

    rebuild(element) {
        // TODO: Add geometry to the host element's shell.
    };

    // --------------------------------------------------------------------
    // Overridden Static Methods - Entity.

    static getEntityType() {
        return g_myNewEntityTypeValue;
    };

    static getDisplayName() {
        return 'My Custom Component';
    };

    static getClassDescription() {
        return 'A parametric widget for doofing a shlumberger.';
    };

    static getClassName() {
        return 'MyLibrary.MyNewComponent';
    };

    // --------------------------------------------------------------------
    // Overridden Static Methods - Component.

    /**
     * Allows the UI to determine which entities this component can be added to.
     */
    static isCompatibleWith(obj) {
        if (isNaN(obj)) return obj.isMyNewElement;
        return (obj == g_myNewEntityTypeValue);
    };

    /**
     * Allows the UI to create an element to host this component.
     */
    static getHostElementClass() {
        return MyLibrary.MyNewElement;
    };

    /**
     * Allows the UI and other classes to distinguish this particular component.
     */
    static subType() {
        return 1;
    };

};

// Register component class with an SVG icon.
PD.Registry.registerClass(MyLibrary.MyNewComponent, {
    content: '<g fill="none" stroke="currentColor"><path d="M10 10L990 0L990 990L0 990z" stroke-width="20"/></g>'
});
// Create and register a new entity type.
const g_myNewEntityTypeValue = BIM.ENTITY.addCustomType('NewEntity');

// Create new entity class.
MyLibrary.NewEntity = class extends BIM.Entity {

    constructor(config, typeName) {
        super(config, typeName || 'NewEntity');
    };

    // --------------------------------------------------------------------
    // Instance Methods.

    get isNewEntity() {
        return true;
    };

    // --------------------------------------------------------------------
    // Static Methods.

    static getEntityType() {
        return g_myNewEntityTypeValue;
    };

    static getDisplayName() {
        return 'My Custom Entity';
    };

    static getClassDescription() {
        return 'The base for physical entities.';
    };

    static getClassName() {
        return 'MyLibrary.MyEntity';
    };

};